import { Logger } from '@/components/useLogger';

import {
  createApplication,
  createContainer,
  createKeyPair,
  deleteApplication,
  devAuth,
  enumCertContainer,
  enumDevice,
  exportPubKey,
  getApplicationList,
  loadLibrary,
  login,
  loginSoPin,
  makeRequest,
} from './usbKeyMethod';

// 注册角色函数
export async function registerRole(
  applicationName: string,
  authPassWd: string,
  soPin: string,
  soPinRetryCount: number,
  userPin: string,
  userPinRetryCount: number,
  rights: number,
  containerName: string,
  keySpec: number,
  asymAlg: number,
  ulKeyLength: number,
): Promise<string> {
  try {
    const loadLibraryResult = await loadLibrary(
      'mtoken_gm3000.dll',
      'libgm3000.1.0.so',
      'libgm3000.1.0.dylib',
    );
    if (loadLibraryResult.rtn !== 0) {
      throw new Error(`加载库失败，错误码: ${loadLibraryResult.errorCode}`);
    }

    // 查找设备
    const devices = await enumDevice();
    if (devices.rtn !== 0 || !devices.array || devices.array.length === 0) {
      throw new Error('未找到任何设备');
    }

    // 处理以 "||" 分隔的设备名字符串
    const deviceNames = devices.array.split('||');
    const deviceName = deviceNames[0]; // 假设我们使用第一个设备

    // USBKey初始化
    const initializeResult = await makeRequest({
      function: 'SOF_Initialize',
      deviceName,
    });
    if (initializeResult.rtn !== 0) {
      throw new Error(`初始化失败，错误码: ${initializeResult.errorCode}`);
    }

    // 认证设备
    const devAuthResult = await devAuth(deviceName, authPassWd);
    if (devAuthResult.rtn !== 0) {
      throw new Error(`设备认证失败，错误码: ${devAuthResult.errorCode}`);
    }

    // 删除USBKey所有应用
    const applications = await getApplicationList(deviceName);
    if (applications.rtn !== 0) {
      throw new Error(`获取应用列表失败，错误码: ${applications.errorCode}`);
    }

    const apps = applications.array.split('||');
    for (const app of apps) {
      if (app && app !== '') {
        const deleteAppResult = await deleteApplication(deviceName, app);
        if (deleteAppResult.rtn !== 0) {
          throw new Error(`删除应用失败，错误码: ${deleteAppResult.errorCode}`);
        }
      }
    }

    // 创建应用
    const createAppResult = await createApplication(
      deviceName,
      applicationName,
      soPin,
      soPinRetryCount,
      userPin,
      userPinRetryCount,
      rights,
    );
    if (createAppResult.rtn !== 0) {
      throw new Error(`创建应用失败，错误码: ${createAppResult.errorCode}`);
    }

    // 验证应用管理密码 soPin
    const loginSoPinResult = await loginSoPin(deviceName, soPin);
    if (loginSoPinResult.rtn !== 0) {
      throw new Error(`应用管理 PIN 验证失败，错误码: ${loginSoPinResult.errorCode}`);
    }

    // 验证用户PIN
    const loginUserResult = await login(deviceName, userPin);
    if (loginUserResult.rtn !== 0) {
      throw new Error(`用户 PIN 登录失败，错误码: ${loginUserResult.errorCode}`);
    }

    // 创建容器
    const createContainerResult = await createContainer(deviceName, containerName);
    if (createContainerResult.rtn !== 0) {
      throw new Error(`创建容器失败，错误码: ${createContainerResult.errorCode}`);
    }

    // 打开容器
    const containers = await enumCertContainer(deviceName);
    if (containers.rtn !== 0 || !containers.containerName) {
      throw new Error(`获取容器名失败，错误码: ${containers.errorCode}`);
    }
    const container = containers.containerName;

    // 生成SM2签名密钥对
    const createKeyPairResult = await createKeyPair(
      container,
      keySpec,
      asymAlg,
      ulKeyLength,
    );
    if (createKeyPairResult.rtn !== 0) {
      throw new Error(`生成密钥对失败，错误码: ${createKeyPairResult.errorCode}`);
    }

    // 获取签名公钥  1为国密结构体格式，2为DER格式，3 为裸数据格式
    const publicKey = await exportPubKey(container, deviceName, keySpec, 3);
    if (publicKey.rtn !== 0) {
      throw new Error(`导出公钥失败，错误码: ${publicKey.errorCode}`);
    }

    return publicKey.pubKey;
  } catch (error) {
    Logger('usbKey注册角色失败:', error);
    throw error;
  }
}

export async function UsbRegisterRole() {
  const applicationName = 'GM3000RSA1'; // 应用名称
  const authPassWd = '1234567812345678'; // 设备认证密码
  const soPin = 'admin'; // 创建的应用管理密码
  const soPinRetryCount = 10; // SO pin码重试次数
  const userPin = '12345678'; // 用户密码
  const userPinRetryCount = 10; // 用户pin码重试次数
  const rights = 16; // 创建应用时指定的权限参数
  const containerName = 'container1'; // 容器名称
  const keySpec = 1; // 根据实际需求设置 1:签名密钥对 2:加密密钥对
  const asymAlg = 131328; // 非对称算法类型 131328：SGD_SM2_1 65536：SGD_RSA
  const ulKeyLength = 256; // SM2的密钥长度为256，RSA的密钥长度为1024/2048

  try {
    const publicKey = await registerRole(
      applicationName,
      authPassWd,
      soPin,
      soPinRetryCount,
      userPin,
      userPinRetryCount,
      rights,
      containerName,
      keySpec,
      asymAlg,
      ulKeyLength,
    );
    Logger('注册角色成功，公钥:', publicKey);
    return publicKey;
  } catch (error: any) {
    throw new Error(error?.message);
  }
}
